package com.quad.innovators.salesease.service.impl.base;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quad.innovators.salesease.common.result.PageResultBean;
import com.quad.innovators.salesease.common.utils.SystemCodeUtils;
import com.quad.innovators.salesease.converter.ShopConverter;
import com.quad.innovators.salesease.enums.ResultCode;
import com.quad.innovators.salesease.enums.StatusEnum;
import com.quad.innovators.salesease.enums.SystemCodeEnum;
import com.quad.innovators.salesease.exception.BusinessException;
import com.quad.innovators.salesease.mapper.base.ShopMapper;
import com.quad.innovators.salesease.model.common.Option;
import com.quad.innovators.salesease.model.entity.base.Shop;
import com.quad.innovators.salesease.model.form.base.ShopForm;
import com.quad.innovators.salesease.model.query.base.ShopPageQuery;
import com.quad.innovators.salesease.model.vo.base.ShopVO;
import com.quad.innovators.salesease.service.base.ShopBrandProviderService;
import com.quad.innovators.salesease.service.base.ShopService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements ShopService {

    private final ShopConverter shopConverter;

    @Override
    public PageResultBean<ShopVO> listPaged(ShopPageQuery queryParams) {
        Page<ShopVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
        Page<ShopVO> shopVOPage = this.baseMapper.listPaged(page, queryParams);
        return shopConverter.toPageVo(shopVOPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(ShopForm form) {
        Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<Shop>()
                .eq(Shop::getName, form.getName())
        );
        if(count > 0){
            throw BusinessException.resultCode(ResultCode.ALREADY_EXISTS_ERROR);
        }
        Shop entity = shopConverter.toEntity(form);
        entity.setCode(SystemCodeUtils.getCode(SystemCodeEnum.SHOP));
        this.baseMapper.insert(entity);
        return true;
    }

    @Override
    public ShopForm getFormData(String code) {
        Shop formData = this.baseMapper.getFormDataByCode(code);
        if(formData == null) {
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        // 查询关联的品牌方
        return shopConverter.toForm(formData);
    }

    @Override
    public boolean update(String code, ShopForm form) {
        Shop formData = this.baseMapper.getFormDataByCode(code);
        if(formData == null){
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        // 是否已经存在
        Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<Shop>()
                .eq(Shop::getName, form.getName())
                .ne(Shop::getCode, code)
        );
        if(count > 0){
            throw BusinessException.resultCode(ResultCode.ALREADY_EXISTS_ERROR);
        }
        Shop entity = shopConverter.toEntity(form);
        entity.setId(formData.getId());
        this.baseMapper.updateById(entity);
        return true;
    }

    @Override
    public boolean updateStatus(String code, Integer status) {
        Shop formData = this.baseMapper.getFormDataByCode(code);
        if(formData == null){
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        formData.setStatus(status);
        this.baseMapper.updateById(formData);
        return true;
    }

    @Override
    public List<Option<String>> listOptions() {
        List<Shop> shops = this.baseMapper.selectList(new LambdaQueryWrapper<Shop>().eq(Shop::getStatus, StatusEnum.ENABLE.getValue()));
        return shops.stream().map(it -> new Option<>(it.getCode(), it.getName())).collect(Collectors.toList());
    }
}
